package com.carkeeper.serve.service.impl;

import com.carkeeper.serve.dao.EsKnowledgeMapper;
import com.carkeeper.entity.Result;
import com.carkeeper.entity.StatusCode;
import com.carkeeper.mapper.KnowledgeMapper;
import com.carkeeper.pojo.KnowledgeBaseInfo;
import com.carkeeper.serve.service.KnowledgeService;
import com.carkeeper.utils.IdWorker;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;


@Service
public class KnowledgeServiceImpl implements KnowledgeService {

    @Autowired
    private EsKnowledgeMapper esKnowledgeMapper;

    @Autowired
    private KnowledgeMapper knowledgeMapper;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;


    @Autowired
    private IdWorker idWorker;

    /**
     * 批量导入
     *
     * @return
     */
    @Override
    public Result<String> batchSingleAddES() {
        try {
            //查询knowledge全部类容
            List<KnowledgeBaseInfo> knowledgeBaseInfos = knowledgeMapper.selectAll();
            //批量存入索引库
            esKnowledgeMapper.saveAll(knowledgeBaseInfos);
            return new Result<String>(true, StatusCode.OK, "批量导入成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result<String>(false, StatusCode.ERROR, "批量导入失败！");
        }

    }

    /**
     * 多条件查询
     *
     * @return
     */
    @Override
    public Result<List<KnowledgeBaseInfo>> showAllKnowledge(Map<String, String> map, String currentPage, String pageSize) {

        //创建条件添加对象
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder);

        //判断是否有推文名称查询条件
        String name = map.get("name");
        if (StringUtils.isNotBlank(name)) {
            //添加并要筛选条件
            boolQueryBuilder.must(QueryBuilders.matchQuery("name", name).operator(Operator.AND));
        }

        //判断总分类是否有查询条件
        String type = map.get("type");
        if (StringUtils.isNotBlank(type)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("type", type));
        }

        //判断一级分类是否有查询条件
        String type01Name = map.get("type01Name");
        if (StringUtils.isNotBlank(type01Name)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("type01Name", type01Name));
        }

        //判断二级分类是否有查询条件
        String type02Name = map.get("type02Name");
        if (StringUtils.isNotBlank(type02Name)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("type02Name", type02Name));
        }

        currentPage = currentPage == null || "".equals(currentPage.trim()) ? "1" : currentPage;
        pageSize = pageSize == null || "".equals(pageSize.trim()) ? "10" : pageSize;
        try {
            nativeSearchQueryBuilder.withPageable(PageRequest.of(Integer.parseInt(currentPage)-1,Integer.parseInt(pageSize)));
        } catch (NumberFormatException e) {
            e.printStackTrace();
            throw new RuntimeException("请输入正确的分页信息！");
        }

        //执行查询
        AggregatedPage<KnowledgeBaseInfo> page = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), KnowledgeBaseInfo.class);

        //获取查询结果
        List<KnowledgeBaseInfo> content = page.getContent();


        return new Result<>(true, StatusCode.OK, "查询成功！", content);
    }





    /**
     * 查询全部分类
     *
     * @param map
     * @return
     */
    @Override
    public Result<Map<String, List<String>>> findCategory(Map<String, String> map) {

        //创建添加条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //执行条件
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder);


        String id = map.get("id");
        if (StringUtils.isNotBlank(id)) {
            //根据id查询
            boolQueryBuilder.must(QueryBuilders.termQuery("id", id));
        }

        //判断总分类是否有查询条件
        String type = map.get("type");
        if (StringUtils.isNotBlank(type)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("type", type));
        }

        //判断一级分类是否有查询条件
        String type01Name = map.get("type01Name");
        if (StringUtils.isNotBlank(type01Name)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery(type01Name, "type01Name"));
        }

        //判断二级分类是否有查询条件
        String type02Name = map.get("type02Name");
        if (StringUtils.isNotBlank(type02Name)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery(type02Name, "type02Name"));
        }

        type = "type";
        //添加聚合函数
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(type).field("type"));

        String type01 = "type01Name";
        //添加聚合函数
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(type01).field("type01Name"));

        String type02 = "type02Name";
        //添加聚合函数
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(type02).field("type02Name"));


        //开始查询
        AggregatedPage<KnowledgeBaseInfo> page = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), KnowledgeBaseInfo.class);
        //获取聚合完毕内容
        Aggregation aggregation = (StringTerms) page.getAggregation(type);
        Aggregation aggregation01 = (StringTerms) page.getAggregation(type01);
        Aggregation aggregation02 = (StringTerms) page.getAggregation(type02);
        //创建集合
        List aggregationList = new ArrayList<String>();
        List aggregation01List = new ArrayList<String>();
        List aggregation02List = new ArrayList<String>();
        List<StringTerms.Bucket> buckets = ((StringTerms) aggregation01).getBuckets();
        //遍历
        for (StringTerms.Bucket bucket : buckets) {
            aggregation01List.add(bucket.getKeyAsString());
        }
        List<StringTerms.Bucket> buckets1 = ((StringTerms) aggregation02).getBuckets();
        //遍历
        for (StringTerms.Bucket bucket : buckets1) {
            aggregation02List.add(bucket.getKeyAsString());
        }
        List<StringTerms.Bucket> buckets2 = ((StringTerms) aggregation).getBuckets();
        //遍历
        for (StringTerms.Bucket bucket : buckets2) {
            aggregationList.add(bucket.getKeyAsString());
        }
        //创建map集合封装返值
        Map<String, List> resultMap = new HashMap<>();
        resultMap.put("type", aggregationList);
        resultMap.put("type01Name", aggregation01List);
        resultMap.put("type02Name", aggregation02List);


        return new Result<>(true, StatusCode.OK, "查询分类成功！", resultMap);
    }

    /**
     * 添加推文
     *
     * @param knowledgeBaseInfo
     * @return
     */
    @Override
    public Result addKnowledgeBaseInfo(KnowledgeBaseInfo knowledgeBaseInfo) {
        //使用雪花算法添加id
        knowledgeBaseInfo.setId(idWorker.nextId());

        try {

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();
            String format = simpleDateFormat.format(date);
            knowledgeBaseInfo.setCreateTime(format);
            knowledgeBaseInfo.setUpdateTime(format);
            //添加到索引库
            KnowledgeBaseInfo save = esKnowledgeMapper.save(knowledgeBaseInfo);
            //添加到数据库
            knowledgeMapper.insert(knowledgeBaseInfo);
            System.out.println("save = " + save);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, StatusCode.ERROR, "添加失败");
        }
        return new Result(true, StatusCode.OK, "添加成功！");
    }


    /**
     * 更新推文
     *
     * @param knowledgeBaseInfo
     * @return
     */
    @Override
    public Result update(KnowledgeBaseInfo knowledgeBaseInfo) {
        if (knowledgeBaseInfo == null) {
            throw new RuntimeException("对象不能为空！");
        }

        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();
            String format = simpleDateFormat.format(date);
            knowledgeBaseInfo.setUpdateTime(format);
            esKnowledgeMapper.save(knowledgeBaseInfo);
            //修改数据库
            knowledgeMapper.updateByPrimaryKeySelective(knowledgeBaseInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, StatusCode.ERROR, "修改失败！");
        }
        return new Result(true, StatusCode.OK, "修改成功！");
    }


    /**
     * 删除推文
     *
     * @param id
     * @return
     */
    @Override
    public Result delete(Long id) {
        if (StringUtils.isBlank(String.valueOf(id))) {
            throw new RuntimeException("数据为空！");
        }

        try {
            //删除es中的数据
            esKnowledgeMapper.deleteById(id);
            //删除数据库中的数据
            knowledgeMapper.deleteByPrimaryKey(id);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, StatusCode.ERROR, "删除失败！");
        }
        return new Result(true, StatusCode.OK, "删除成功！");


    }

    /**
     * 根据分类查询知识库
     * @param type
     * @return
     */
    @Override
    public Result<List<KnowledgeBaseInfo>> findKnowledgeByCategory(String type) {

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder);

        boolQueryBuilder.must(QueryBuilders.termQuery("type", type));

        AggregatedPage<KnowledgeBaseInfo> page = elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), KnowledgeBaseInfo.class);
        List<KnowledgeBaseInfo> content = page.getContent();

        return new Result<>(true,StatusCode.OK,"查询成功！",content);
    }
}
